#!/usr/bin/python

### README ###
# You can make a config file called .gooshell in your home directory
# Syntax is on the Wiki on Google Code
# Variable com is two parts. com[0] is the base command input, com[1:] is anything after
# This program should be really easily moddable and you can add anything to it
'''
    This program is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation, either version 3 of the License, or
    (at your option) any later version.

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with this program.  If not, see <http://www.gnu.org/licenses/>.
'''

### IMPORTS ###

from os import system
from getpass import getuser
from commands import getoutput
from webbrowser import open_new_tab
from re import compile

### END IMPORTS ###

### DEFAULTS ###

url      = {'web': 'http://www.google.com/search?q=', 'img': 'http://www.google.com/images?q=', 'vid': 'http://www.google.com/#tbm=vid&q=', 'maps': 'http://maps.google.com/maps?q=', 'news': 'http://news.google.com/news?q=', 'shop': 'http://www.google.com/search?tbs=shop:1&q=', 'wmmd': 'http://en.wikipedia.org/wiki/'} # Dictionary containing base URLs for search command
cddb     = ['web', 'img', 'vid', 'maps', 'news', 'shop', 'wmmd'] # cd database
mode     = 'web' # Default mode
server   = 'gooshell' # Default server name
homedir  = getoutput('echo $HOME')
user     = getuser()
defbrow  = ''
tops     = 5
valcom   = ['ls', 'clear', 'exit', 'help', 'cd', 'search', 'wikimode'] ## Valid commands

### END DEFAULTS ###

### PRECURSORS ###

try:
	a = file('%s/.gooshell' % homedir, 'r') # Try to load conf file
except:
	pass
else:
	settings = a.read()
	a.close()
	print "Found custom settings file."
	print "Using custom settings."
	settings = settings.split('\n')
	for line in settings:
		if line.startswith('defbrow '):
			defbrow = line
			defbrow = defbrow.replace('defbrow ', '', 1)
		if line.startswith('servname '):
			server = line
			server = server.replace('servname ', '', 1)
		if line.startswith('defmode '):
			mode = line.replace("defmode ", '', 1)
			if mode not in cddb:
				mode = 'web'
				print "Config file error: %s not a valid mode" % line.replace('defmode ', '', 1)
		if line.startswith('resultsn '):
			tops = line.replace('resultsn ', '')
			res = compile(r'[^\d]+')
			tops = res.sub('', tops)
			if tops == '':
				tops = 5
			

### END PRECURSORS ###

### FUNCTIONS ###

def rreplace(s, old, new, count):
	return (s[::-1].replace(old[::-1], new[::-1], count))[::-1]

def rep(result):
    string = result.group()                   # "&#xxx;"
    n = int(string[2:-1])
    uchar = unichr(n)                         # matching unicode char
    # for you dest format may be iso-8859-2 ?
    return unicode.encode(uchar, "utf-8")     # format-encoded char

def remstup(data):
	return data.replace("&quot;", "'").replace("&nbsp;", " ").replace("&amp;", "&")

def webopen(url): ## Open URL 'url' with default browser or defbrow in conf file
	global defbrow
	global tops
	if mode == 'wmmd':
		data = getoutput('curl %s' % url)
		data = data.partition('<p>')
		data = data[2].partition('</p>')
		data = remove_html_tags(data[0])
		print data
	elif mode == 'web':
		googpage = getoutput("curl --silent \"%s\" -A \"Mozilla/5.0 (X11; Linux x86_64; rv:2.2a1pre) Gecko/20110324 Firefox/4.2a1pre\"" % url)
		googpage = googpage.partition('<h2 class=hd>Search Results</h2>')
		googpage = googpage[2].partition('</ol>')
		'''
		googpage = googpage[0].replace("<br>", "\n")
		googpage = remove_html_tags(googpage)
		print googpage
		'''
		googpage = googpage[0].split("<h3 class=\"r\">")
		googleng = len(googpage)
		counter = 1
		while counter < tops:
			if counter < googleng:
				pat = compile("""&#\d+;""")
				title = googpage[counter].partition('</h3>')[0]
				print str(counter) + ". " + pat.sub(rep, remstup(remove_html_tags(title)))
				desc =  "      " + remove_html_tags(googpage[counter].partition('</h3>')[2].split("<div class=\"s\">")[1].partition('<span class=f')[0])
				pat = compile("""&#\d+;""")
				print pat.sub(rep, remstup(desc))
				print "      " + remove_html_tags(googpage[counter].partition('</h3>')[0].split("<a href=\"")[1].partition('\"')[0])
				print
				counter = counter + 1
		#print googpage
		#print remove_html_tags(googpage[4].partition('</h3>')[0])
	else:
		if defbrow == '':
			print
			open_new_tab(sturl)
		else:
			print
			system('%s \'%s\'' % (defbrow, url))

def remove_html_tags(data):
    p = compile(r'<[^<]*?>')
    return p.sub('', data)

def exit():
	quit()

def misarg(): ## Missing args
	print "Command '%s' is missing arguments. Use command 'help' to find out syntax." % com[0]
	
def main():
	global com
	global mode
	if mode == 'wmmd':
		com = raw_input("%s@%s:%s# " % (user, server, mode)).split(" ")
		com[0] = com[0].lower()
	else:
		com = raw_input("%s@%s:%s# " % (user, server, mode)).lower().split(" ")
	if com[0] not in valcom:
		print "Unknown command: %s" % com[0]
	else:
		if com[0] == 'exit':
			exit()
		elif com[0] == 'ls':
			for value in cddb:
				print value
		elif com[0] == 'help':
			for value in valcom:
				print value
		elif com[0] == 'clear':
			system('clear')
		elif com[0] == 'wikimode':
			print "Wikimode searches Wikipedia and tries to withdraw the first paragraph of information on your search terms. Capitalization MATTERS."
			mode = 'wmmd'
		elif com[0] == 'search':
			try:
				com[1]
			except IndexError:
				misarg()
			else:
				st = com[1:]
				st = ' '.join(st)
				if mode == 'wmmd':
					st = st.replace(' ', '_')
				else:
					st = st.replace(" ", "%20")
				sturl = url[mode] + st
				webopen(sturl)
		elif com[0] == 'cd':
			try:
				com[1]
			except IndexError:
				misarg()
			else:
				if com[1] in cddb:
					if com[1] == 'wmmd':
						print "Use the command 'wikimode' to enable this mode."
					else:
						mode = com[1].lower()
				else:
					print "Mode '%s' is not a valid mode. Try 'ls' for mode listing." % com[1]

### END FUNCTIONS ###

### MAIN WORKLOAD ###
		
while True:
	main()

### END MAIN WORKLOAD ###

quit() # Trailing quit for safety...
